Skip to content

Release/1.5.0#64

Merged
mehul0810 merged 40 commits intomasterfrom
release/1.5.0
Nov 3, 2025
Merged

Release/1.5.0#64
mehul0810 merged 40 commits intomasterfrom
release/1.5.0

Conversation

@mehul0810
Copy link
Collaborator

@mehul0810 mehul0810 commented Nov 3, 2025

Changes

  • Migrated the settings to WP Design System and React based UI
  • Restructured the organization of the settings for better context

@mehul0810 mehul0810 requested a review from Copilot November 3, 2025 05:03
@github-actions
Copy link

github-actions bot commented Nov 3, 2025

Test on Playground
Test this pull request on the Playground

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a major refactoring of the Perform plugin's settings interface, migrating from a traditional PHP-rendered settings page to a React-based single-page application. The changes update the plugin to version 1.5.0 and change the license from GPLv2 to GPLv3.

Key changes:

  • React-based settings UI using WordPress components
  • Centralized settings field definitions in Helpers class
  • Enhanced security with nonce verification and capability checks
  • Improved field sanitization logic based on field types
  • Updated GitHub repository references and bug report URLs

Reviewed Changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
perform.php Updates version to 1.5.0 and changes license to GPLv3
package.json Adds WordPress React dependencies and updates version/license
webpack.config.js Updates GitHub repository URL and removes trailing space
src/Includes/Helpers.php Adds extensive settings field definitions and helper methods
src/Admin/Settings/Menu.php Refactors to use React app with localized data
src/Admin/Actions.php Adds WordPress components and localizes settings data
assets/src/js/admin/*.jsx New React components for settings interface
assets/src/css/admin/settings.css New styles for React-based settings page

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return array_map( [ __CLASS__, __METHOD__ ], $var );
} else {
return is_scalar( $var ) ? sanitize_text_field( wp_unslash( $var ) ) : $var;
// Recursively clean array values by calling this same method.
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The refactored code now uses an explicit method name 'clean' instead of METHOD. While this works correctly, the original METHOD approach was more maintainable as it would automatically update if the method is renamed. Consider adding a comment explaining why the explicit method name is preferred here, or document that method renaming should update this reference.

Suggested change
// Recursively clean array values by calling this same method.
// Recursively clean array values by calling this same method.
// Note: The method name 'clean' is used explicitly here for recursion.
// If this method is renamed, update the string 'clean' accordingly.

Copilot uses AI. Check for mistakes.
// If associative array (value=>label) check keys, otherwise check values
$keys = array_keys( $opts );
$vals = array_values( $opts );
if ( array_diff_key( $opts, array_values( $opts ) ) ) {
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic to detect associative arrays is unclear and potentially fragile. The condition checks if the array has different keys after array_values(), but this is an indirect way to detect associative arrays. Consider using a clearer approach like checking if array_keys($opts) !== range(0, count($opts) - 1) or adding a helper function with a descriptive name like 'is_associative_array()'.

Suggested change
if ( array_diff_key( $opts, array_values( $opts ) ) ) {
if ( array_keys( $opts ) !== range( 0, count( $opts ) - 1 ) ) {

Copilot uses AI. Check for mistakes.
setSaving(true);
setMessage(null);
try {
const res = await fetch(ajaxurl, {
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code uses the global 'ajaxurl' variable without checking if it exists. While this is typically available in WordPress admin, it's better to access it safely via window.ajaxurl or provide a fallback. Consider adding a check or using window.performwpSettings to pass the ajax URL explicitly.

Suggested change
const res = await fetch(ajaxurl, {
const ajaxUrl = window.performwpSettings?.ajaxurl || window.ajaxurl;
if (!ajaxUrl) {
throw new Error('AJAX URL not defined.');
}
const res = await fetch(ajaxUrl, {

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +65
// mutate initialValues object won't update memo, so reset by rebuild: setFieldValues equals current, but we need to reset initialValues - simplest approach: set initial snapshot to current by resetting via a state.
// We'll set the initialValues by replacing the state used for comparison: emulate by setting all initialValues to current values via a ref - but here we'll just clear dirty by resetting initialValues via resetting fieldValues baseline.
// For simplicity, update initialValues by assigning to window.performwpSettings._initial = fieldValues (not ideal), but we can update local initialValues via a small trick: setFieldValues to same and update a savedSnapshot state.
// Implement savedSnapshot state instead.
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These commented-out thoughts/implementation notes should be removed. They describe the problem-solving process but don't add value to the final code. The implementation using savedSnapshot is clear from the code itself. Remove these comments to improve code cleanliness.

Suggested change
// mutate initialValues object won't update memo, so reset by rebuild: setFieldValues equals current, but we need to reset initialValues - simplest approach: set initial snapshot to current by resetting via a state.
// We'll set the initialValues by replacing the state used for comparison: emulate by setting all initialValues to current values via a ref - but here we'll just clear dirty by resetting initialValues via resetting fieldValues baseline.
// For simplicity, update initialValues by assigning to window.performwpSettings._initial = fieldValues (not ideal), but we can update local initialValues via a small trick: setFieldValues to same and update a savedSnapshot state.
// Implement savedSnapshot state instead.

Copilot uses AI. Check for mistakes.
}
});


Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file contains both the new React app initialization (lines 4-12) and what appears to be legacy code for the old form-based settings (lines 15+). If the old PHP-rendered form is no longer used, this legacy code should be removed. If both approaches coexist during a transition period, add comments explaining this temporary state.

Suggested change
// TEMPORARY: The following legacy form-handling code is retained during the transition to the new React-based settings page.
// Once all settings functionality has been migrated to React, this code can be safely removed.

Copilot uses AI. Check for mistakes.
justifyContent: 'flex-end',
gap: 12,
alignItems: 'center',
marginBottom: '-20px',
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using a negative margin to adjust positioning is a code smell that suggests the layout structure may need adjustment. Consider reviewing the parent container's padding/margin instead of using negative values, which can cause unexpected layout issues and make the component less reusable.

Suggested change
marginBottom: '-20px',

Copilot uses AI. Check for mistakes.
$sanitized_post[ $key ] = sanitize_text_field( $raw_val );
}
} else {
// No field definition found – fall back to a safe cleaning
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When no field definition is found, the code falls back to sanitize_text_field for scalar values. However, this may not be appropriate for all field types (e.g., URLs, emails, numbers). Consider logging a warning when a field definition is not found, as this could indicate a mismatch between frontend and backend field definitions, potentially allowing unsanitized data if Helpers::clean() doesn't handle the specific data type properly.

Suggested change
// No field definition found – fall back to a safe cleaning
// No field definition found – log a warning and fall back to a safe cleaning
error_log(
sprintf(
'[Perform] Warning: No field definition found for key "%s" with value "%s". Falling back to sanitize_text_field or Helpers::clean. This may indicate a mismatch between frontend and backend field definitions.',
$key,
is_scalar( $raw_val ) ? (string) $raw_val : json_encode( $raw_val )
)
);

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,35 @@
import { Button, Spinner } from '@wordpress/components';
import { useEffect } from '@wordpress/element';
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import useEffect.

Suggested change
import { useEffect } from '@wordpress/element';

Copilot uses AI. Check for mistakes.
@mehul0810 mehul0810 merged commit 3030abf into master Nov 3, 2025
1 of 10 checks passed
@mehul0810 mehul0810 deleted the release/1.5.0 branch November 3, 2025 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants